package com.maoye.ossp.bpm.workflow.controller;

/**
 * 学生Contorller
 * 
 * @author zhuangwl
 * @date 2013-12-16
 * @version 1.0
 */
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.hotent.base.api.Page;
import com.hotent.base.api.query.Direction;
import com.hotent.base.api.query.FieldSort;
import com.hotent.base.api.query.QueryFilter;
import com.hotent.base.api.query.QueryOP;
import com.hotent.base.core.util.string.StringUtil;
import com.hotent.base.db.model.DefaultQueryFilter;
import com.hotent.base.db.mybatis.domain.DefaultFieldSort;
import com.hotent.base.db.mybatis.domain.DefaultPage;
import com.hotent.base.db.mybatis.domain.PageList;
import com.hotent.base.db.mybatis.domain.PageResult;
import com.hotent.bpmx.api.model.process.def.BpmDefLayout;
import com.hotent.bpmx.api.model.process.def.BpmDefinition;
import com.hotent.bpmx.api.model.process.inst.BpmProcessInstance;
import com.hotent.bpmx.api.model.process.task.BpmTaskOpinion;
import com.hotent.bpmx.api.service.BpmDefinitionService;
import com.hotent.bpmx.api.service.BpmInstService;
import com.hotent.bpmx.api.service.BpmOpinionService;
import com.hotent.bpmx.api.service.BpmTaskService;
import com.hotent.bpmx.api.service.DiagramService;
import com.hotent.bpmx.api.service.FlowStatusService;
import com.maoye.ossp.bpm.workflow.service.IBpmWorkFlowService;
import com.maoye.ossp.bpm.workflow.service.IProcessService;
import com.maoye.ossp.bpm.workflow.util.WorkflowConstants;
import com.maoye.ossp.common.util.RequestContext;
import com.maoye.ossp.common.web.BaseController;
import com.maoye.ossp.sys.org.util.UserUtils;

@Controller
@RequestMapping(value = "/bpm/workflow/")
public class BpmWorkFlowController extends BaseController {

	@Resource
	IBpmWorkFlowService bpmWorkFlowService;

	@Resource
	BpmOpinionService bpmOpinionService;

	@Resource
	BpmInstService bpmInstService;

	@Resource
	BpmTaskService bpmTaskService;

	@Resource
	DiagramService diagramService;

	@Resource
	FlowStatusService flowStatusService;

	@Resource
	BpmDefinitionService bpmDefinitionService;

	@Resource
	private IProcessService processService;

	/**
	 * 流程公共执行任务（拦截）
	 * 
	 * @param redirectAttributes
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "executeTask")
	@ResponseBody
	public String executeTask(RedirectAttributes redirectAttributes,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		JSONObject obj = new JSONObject();
		try {
			String busKey = request.getParameter("busKey");
			Map<String, Object> params = new HashMap<String, Object>();
			bpmWorkFlowService.executeTask(busKey, params);
			// addMessage(redirectAttributes, "执行任务成功！");
			obj.element("type", "success");
		} catch (Exception e) {
			obj.element("type", "error");
			obj.element("msg", e.getMessage());
			throw e;
		}
		return obj.toString();
	}

	/**
	 * 获取新增或编辑页面流程信息
	 * 
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "getWorkFlowInfoByEdit")
	@ResponseBody
	public Map<String, Object> getWorkFlowInfoByEdit(
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 定义返回值
		Map<String, Object> workFlowMap = bpmWorkFlowService
				.getWorkFlowInfoByEdit(new RequestContext(request));
		return workFlowMap;
	}

	/**
	 * 获取查看页面流程信息
	 * 
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "getWorkFlowInfoByView")
	@ResponseBody
	public Map<String, Object> getWorkFlowInfoByView(
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 定义返回值
		Map<String, Object> workFlowMap = bpmWorkFlowService
				.getWorkFlowInfoByView(new RequestContext(request));
		return workFlowMap;
	}

	/**
	 * 删除流程实例
	 * 
	 * @param bpmProcessInstanceID
	 * @param model
	 * @param redirectAttributes
	 * @return
	 */
	@RequestMapping(value = "{bpmProcessInstanceID}/delete/{method}")
	public String delete(@PathVariable String bpmProcessInstanceID,
			@PathVariable String method, HttpServletRequest request,
			Model model, RedirectAttributes redirectAttributes) {
		boolean isSuccess = false;
		BpmProcessInstance bpmProInst = bpmInstService
				.getProcessInstance(bpmProcessInstanceID);
		if (bpmProInst != null) {
			// 是否为草稿状态
			if (bpmProInst.getStatus().equals(BpmProcessInstance.STATUS_DRAFT)) {
				isSuccess = bpmInstService
						.removeProcessInstance(bpmProcessInstanceID);
			}
			if (isSuccess) {
				try {
					// 更新sap表单状态为DELETE
					processService.updateSapBusinessFormStatus(
							bpmProInst.getProcDefKey(), bpmProcessInstanceID,
							WorkflowConstants.SAP_FORM_STAUS_DELETE);
				} catch (Exception e) {
				}
			}
		}
		String navId = request.getParameter("navId");
		addMessage(redirectAttributes, "删除数据成功！");
		return "redirect:/bpm/workflow/" + method + "?navId=" + navId;
	}

	/**
	 * 得到所有的流程实例
	 * 
	 * @param request
	 * @param response
	 * 
	 * @return
	 */
	@RequestMapping(value = "getAllWorkFlow")
	public String getAllWorkFlow(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		DefaultPage page = (DefaultPage) getPage(request);
		// 设置排序
		List<FieldSort> orders = new ArrayList<FieldSort>();
		DefaultFieldSort sort = new DefaultFieldSort("create_time_",
				Direction.DESC);
		orders.add(sort);
		String subject = (String) request.getParameter("subject");
		DefaultQueryFilter queryFilter = new DefaultQueryFilter();
		queryFilter.setFieldSortList(orders);
		queryFilter.setPage(page);
		if (StringUtils.isNotEmpty(subject)) {
			queryFilter.addFilter("subject_", subject, QueryOP.LIKE);
		}
		PageList<BpmProcessInstance> processInsList = (PageList<BpmProcessInstance>) bpmInstService
				.getAll(queryFilter);
		com.maoye.ossp.common.entity.Page<BpmProcessInstance> localPage = copyPage(processInsList);
		model.addAttribute("page", localPage);
		model.addAttribute("subject", subject);
		return "/bpm/workflow/adminList";
	}

	/**
	 * 得到我发起的流程实例
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "getMyCreateWorkFlow")
	public String getMyCreateWorkFlow(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		Page page = getPage(request);
		PageList<BpmProcessInstance> processInsList = (PageList<BpmProcessInstance>) bpmInstService
				.getProcessInstancesByUserId(UserUtils.getCurrentUserId()
						.toString(), page);
		com.maoye.ossp.common.entity.Page<BpmProcessInstance> localPage = copyPage(processInsList);
		String navId = request.getParameter("navId");
		model.addAttribute("navId", navId);
		model.addAttribute("page", localPage);
		model.addAttribute("method", "getMyCreateWorkFlow");
		return "/bpm/workflow/list";
	}

	/**
	 * 得到我审批的流程实例
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "getMyApprovalWorkFlow")
	public String getMyApprovalWorkFlow(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		DefaultPage page = (DefaultPage) getPage(request);
		// 设置排序
		List<FieldSort> orders = new ArrayList<FieldSort>();
		DefaultFieldSort sort = new DefaultFieldSort("create_time_",
				Direction.DESC);
		page.setOrders(orders);
		// 查询
		PageList<BpmProcessInstance> processInsList = (PageList<BpmProcessInstance>) bpmInstService
				.getByTaskUserId(UserUtils.getCurrentUserId().toString(), page);
		com.maoye.ossp.common.entity.Page<BpmProcessInstance> localPage = copyPage(processInsList);
		String navId = request.getParameter("navId");
		model.addAttribute("navId", navId);
		model.addAttribute("page", localPage);
		model.addAttribute("method", "getMyApprovalWorkFlow");
		return "/bpm/workflow/list";
	}

	/**
	 * 得到我审批过的流程实例
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "getMyPassWorkFlow")
	public String getMyPassWorkFlow(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		DefaultPage page = (DefaultPage) getPage(request);
		// 设置排序
		List<FieldSort> orders = new ArrayList<FieldSort>();
		DefaultFieldSort sort = new DefaultFieldSort("create_time_",
				Direction.DESC);
		orders.add(sort);
		DefaultQueryFilter queryFilter = new DefaultQueryFilter();
		queryFilter.setFieldSortList(orders);
		queryFilter.setPage(page);
		// PageList<BpmProcessInstance> processInsList =
		// (PageList<BpmProcessInstance>)
		// bpmInstService.getAttendProcessInstancesByUserId(UserUtils.getCurrentUserId().toString(),page);
		PageList<BpmProcessInstance> processInsList = (PageList<BpmProcessInstance>) bpmInstService
				.getAttendProcessInstancesByUserId(UserUtils.getCurrentUserId()
						.toString(), queryFilter);
		com.maoye.ossp.common.entity.Page<BpmProcessInstance> localPage = copyPage(processInsList);
		String navId = request.getParameter("navId");
		model.addAttribute("page", localPage);
		model.addAttribute("navId", navId);
		model.addAttribute("method", "getMyPassWorkFlow");
		return "/bpm/workflow/list";
	}

	private com.maoye.ossp.common.entity.Page<BpmProcessInstance> copyPage(
			PageList<BpmProcessInstance> processInsList) {
		com.maoye.ossp.common.entity.Page<BpmProcessInstance> toPage = new com.maoye.ossp.common.entity.Page<BpmProcessInstance>();
		PageResult pageResult = processInsList.getPageResult();
		toPage.setPageNo(pageResult.getPage());
		toPage.setPageSize(pageResult.getLimit());
		toPage.setTotal(pageResult.getTotalCount());
		toPage.setList((ArrayList<BpmProcessInstance>) processInsList);
		return toPage;
	}

	/**
	 * 得到流程审批记录
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "opinions")
	public String view(@RequestParam("proInstID") String proInstID,
			HttpServletRequest request, HttpServletResponse response,
			Model model) {
		List<BpmTaskOpinion> opiList = null;
		// proInstID = (String)request.getAttribute("proInstID");
		opiList = bpmOpinionService.getTaskOpinions(proInstID);
		model.addAttribute("list", opiList);
		return "/bpm/workflow/opinions";
	}

	/**
	 * 进入流程图页面
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("queryFlowImage")
	public String queryFlowImage(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		// String bpmnDefId = request.getParameter("bpmnDefId");
		String instanceId = request.getParameter("instanceId");
		String defId = request.getParameter("defId");

		if (StringUtil.isNotEmpty(instanceId)) {
			BpmProcessInstance bpmProcessInstance = bpmInstService
					.getProcessInstance(instanceId);
			if (bpmProcessInstance != null) {
				defId = bpmProcessInstance.getProcDefId();
			}
		}

		if (StringUtil.isNotEmpty(defId)) {
			BpmDefinition def = bpmDefinitionService
					.getBpmDefinitionByDefId(defId);
			if (def != null && StringUtil.isNotEmpty(def.getBpmnDefId())) {
				BpmDefLayout layout = diagramService.getLayoutByDefId(def
						.getDefId());
				request.setAttribute("bpmDefLayout", layout);
				request.setAttribute("bpmDef", def);
			}
		}

		request.setAttribute("instanceId", instanceId);
		request.setAttribute("defId", defId);
		return "/bpm/workflow/flowImage";
	}

	/**
	 * 获取流程图
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	@RequestMapping(value = "bpmImage")
	public void bpmImage(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0L);

		String defId = request.getParameter("defId");
		String instanceId = request.getParameter("instanceId");

		if (StringUtil.isEmpty(defId)) {
			if (StringUtil.isNotEmpty(instanceId)) {
				BpmProcessInstance bpmProcessInstance = bpmInstService
						.getProcessInstance(instanceId);
				if (bpmProcessInstance != null) {
					defId = bpmProcessInstance.getProcDefId();
				}
			}
		}

		InputStream is = null;
		if (StringUtil.isNotEmpty(defId)) {
			if (StringUtil.isNotEmpty(instanceId)) {
				Map<String, String> status = flowStatusService
						.getProcessInstanceStatus(instanceId);
				is = diagramService.getDiagramByBpmnDefId(defId, status);
			} else {
				is = diagramService.getDiagramByBpmnDefId(defId);
			}
		}

		if (is != null) {
			response.setContentType("image/png");
			OutputStream out = new BufferedOutputStream(
					response.getOutputStream());
			try {
				byte b[] = new byte[1024];
				while (is.read(b) > 0) {
					out.write(b);
				}
			} finally {
				is.close();
				out.close();
			}
		}
	}

	/**
	 * 流程信息展示
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "view")
	public String view(HttpServletRequest request, HttpServletResponse response) {
		//
		String url = null;
		try {
			url = bpmWorkFlowService
					.getWorkFlowUrl(new RequestContext(request));
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (url.startsWith("/")) {
			return "redirect:" + url;
		} else {
			return "redirect:/" + url;
		}

	}
}
